import sys

class Student:
    school = "清华大学"

    @staticmethod
    def calc_bmi(height,weight):
        return round(weight/(height*height),2)
    #类函数
    @classmethod
    def new_instance(cls):
        return cls("工厂制造人",0,170,60)

    def __init__(self,name,age,height,weight):
        self.name = name
        self.age = age
        self.height = height
        self.weight = weight

    #属性装饰器
    @property
    def bmi(self):
        #调用了类的静态方法
        return Student.calc_bmi(self.height,self.weight)

    #属性装饰器
    @property
    def gender(self):
        return self.__gender

    @gender.setter
    def gender(self,value):
        if value not in (0,1):
            raise TypeError("类型不正确")
        self.__gender = value

    @gender.deleter
    def gender(self):
        raise PermissionError("不允许删除")

    def choose(self):
        print(self.name)

def main_stu():
    stu = Student('jack',22,1.65,60)
    print(stu.bmi)

    stu2 = Student('rr',44,1.65,60)
    print(stu.bmi)

    print(id(Student.school))
    print(id(stu.school))

    #方法内存地址不一样
    print("choose func")
    print(id(Student.choose),Student.choose)
    print(id(stu.choose),stu.choose)
    print(id(stu2.choose),stu2.choose)

    print(Student.new_instance)
    print(Student.calc_bmi)

    #通过类来调用函数
    Student.choose(stu)
    Student.choose(stu2)

    print(stu.name)
    stu.gender = 1
    print(stu.gender)

    #下面的删除属性操作会提示错误
    #del stu.gender
    print(Student.__dict__)
    print(stu.__dict__)

    print(Student.mro())
    print(property)


class Animal:
    def __init__(self,name):
        self.__name = name
    # 方案1
    # def set_name(self,name):
    #     if not (type(name) is str):
    #         raise TypeError("必须是字符串类型")
    #     self.__name = name
    #
    # def get_name(self):
    #     return self.__name
    #
    # def delete_name(self):
    #     raise PermissionError("禁止删除属性")
    #
    # name = property(get_name,set_name,delete_name)

    # 方案2

    @property
    def name(self):
        return self.__name
    @name.setter
    def name(self,name):
        if not (type(name) is str):
            raise TypeError("必须是字符串类型")
        self.__name = name


    @name.deleter
    def name(self):
        raise PermissionError("禁止删除属性")

def main_property():
    cat = Animal("猫")
    cat.name = "狗"
    print(cat.name)


class Parent1:
    x = 111
class Parent2:
    pass

class Sub(Parent1):
    pass
class Sub2(Parent1,Parent2):
    pass

def main_mutil():
    #查看继承类
    print(Parent1.__bases__)
    print(Sub.__bases__)
    print(Sub2.__bases__)
    print(Sub2.__base__)

    s1 = Sub()
    s2 = Sub2()
    print(id(s1.x),s1.x)
    print(id(s2.x),s2.x)


class People:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def __str__(self):
        s = ""
        for k in self.__dict__:
            s = s +f"{k}={self.__dict__[k]}\n"
        return s
class Teacher(People):
    def __init__(self,name,age,sex,school):
        super().__init__(name,sex,age)
        self.school = school



#--  多继承问题
class A:
    x = 'a'
    def f1(self):
        print("A.f1")
    def f2(self):
        print("A.f2")
        self.f1()
class B:
    x = 'b'

class C(A,B):
    def show(self):
        print(self.x)

    def f1(self):
        #super(C,self).f1()
        print("C.f1")

class D(B,A):
    def show(self):
        print(self.x)

# C().show()  # a
# D().show()  # b
#C().f2()

#print(C.mro())

#--------- 抽象基类

import abc

class Tax(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def print_tax(self):
        pass


class ZZSTax(Tax):
    def print_tax(self):
        print("增值税")


ZZSTax().print_tax()